﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using InfoKiosk;
using TFSServices.TFS;
using System.ServiceModel.Channels;
using System.ServiceModel;

namespace TFSServices
{
    public partial class BuildStatusPage : UserControl, IInfoPage
    {
        private const Int32 controlWidth = 390;

        public BuildStatusPage()
        {
            InitializeComponent();
        }

        public void Start()
        {
            Binding binding = new BasicHttpBinding();

            String tfsServiceURI = ComponentParameters.Where(
                param => param.Key == "TFSServiceURI").First().Value;

            TfsServiceClient client = new TfsServiceClient(binding,
                new EndpointAddress(tfsServiceURI));

            client.GetBuildStatusCompleted += client_GetBuildStatusCompleted;

            String tfsServerName = ComponentParameters.Where(
                    param => param.Key == "TFSServer").First().Value;

            client.GetBuildStatusAsync(tfsServerName);

        }

        void VerticalLayout(TeamProject[] teamProjects)
        {
            Int32 containerHeight = (Int32)((StackPanel)((BuildStatusPage)LayoutRoot.Parent).Parent).ActualHeight;
            Double maxWidth = CalculateColumnWidth();
            Int32 columnNumber = 0;
            Int32 runningHeight = 0;
            Int32 controlHeight = 0;

            foreach (TeamProject teamProject in teamProjects)
            {
                if ((teamProject.BuildTypes != null) &&
                    (teamProject.BuildTypes.Count() > 0))
                {
                    Boolean showHeader = true;

                    foreach (BuildType buildType in teamProject.BuildTypes)
                    {
                        BuildStatusControl control = new BuildStatusControl();

                        Double scaleFactor = control.Scale(maxWidth);
                        
                        if (!showHeader)
                        {
                            control.Header.Height = new GridLength(0);
                            controlHeight = 80;
                        }
                        else
                        {
                            showHeader = false;
                            controlHeight = 117;
                        }
                      
                        if (runningHeight + (controlHeight * scaleFactor) > containerHeight)
                        {
                            control.Header.Height = new GridLength(37);
                            columnNumber++;
                            runningHeight = 0;
                            controlHeight = 117;
                        }

                        control.SetValue(Canvas.TopProperty, (Double)runningHeight);
                        control.SetValue(Canvas.LeftProperty, (columnNumber * maxWidth) + (columnNumber * 10));

                        if (scaleFactor < 1)
                        {
                            runningHeight += (Int32)(controlHeight * scaleFactor);
                        }
                        else
                        {
                            runningHeight += controlHeight;
                        }

                        runningHeight += 10;    // add spacing between controls

                        control.TeamProjectName.Text = teamProject.Name;

                        control.BuildType.Text = buildType.Name;

                        String buildPostFix = "th";
                        if (buildType.NumberOfConsecutiveBuilds == 1)
                            buildPostFix = "st";
                        if (buildType.NumberOfConsecutiveBuilds == 2)
                            buildPostFix = "nd";

                        String statusText = "successful";

                        control.StatusImageRed.Visibility = Visibility.Collapsed;
                        control.StatusImageGreen.Visibility = Visibility.Collapsed;
                        control.StatusImageYellow.Visibility = Visibility.Collapsed;

                        Boolean isBuilding = false;


                        if (buildType.Status == "Successfully Completed")
                        {
                            control.StatusImageGreen.Visibility = Visibility.Visible;
                            statusText = "Successful";
                            control.BuildStatus.Text = String.Format(
                                "Successful @ {1:dd/MM/yyyy HH:mm:ss}",
                                statusText, buildType.LastBuild);

                        }
                        else if (buildType.Status == "Failed")
                        {
                            control.StatusImageRed.Visibility = Visibility.Visible;
                            statusText = "Broken";
                            control.BuildStatus.Text = String.Format(
                                "Broken @ {1:dd/MM/yyyy HH:mm:ss}",
                                statusText, buildType.LastBuild);
                        }
                        else
                        {
                            control.BuildStatus.Text = buildType.Status;
                            control.StatusImageYellow.Visibility = Visibility.Visible;
                            isBuilding = true;
                        }


                        if ((buildType.NumberOfConsecutiveBuilds > 0) && (!isBuilding))
                        {
                            control.BuildTime.Text = String.Format("{0}{1} consecutive {2} build",
                                buildType.NumberOfConsecutiveBuilds,
                                buildPostFix, statusText);
                        }
                        else
                        {
                            control.BuildTime.Text = String.Format("Started on {0:dd/MM/yyyy HH:mm:ss}",
                                buildType.LastBuild);
                        }


                        LayoutRoot.Children.Add(control);
                    }
                }
            }
        }

        private Double CalculateColumnWidth()
        {

            Double recommendedWidth = LayoutRoot.ActualWidth;

            // Get a sense of how many colums we can get based on the original size
            Int32 numberOfColumns = (Int32)(LayoutRoot.ActualWidth / controlWidth);

            switch (numberOfColumns)
            {
                case 0:
                    numberOfColumns = 1;
                    break;
                case 1:
                    if ((recommendedWidth / (numberOfColumns + 1)) > 250)
                        numberOfColumns += 1;
                    break;
                case 2:
                    if ((recommendedWidth / (numberOfColumns + 1)) > 300)
                        numberOfColumns += 1;
                    break;
                case 3:
                    if ((recommendedWidth / (numberOfColumns + 1)) > 350)
                        numberOfColumns += 1;
                    break;
            }

            // Adjustment for the horizontal spacing
            Double actualWidth = recommendedWidth - ((numberOfColumns - 1) * 10);

            return actualWidth / numberOfColumns;

        }

        void HorizontalLayout(TeamProject[] teamProjects)
        {
            Int32 columnNumber = 0;

            foreach (TeamProject teamProject in teamProjects)
            {
                if ((teamProject.BuildTypes != null) &&
                    (teamProject.BuildTypes.Count() > 0))
                {
                    columnNumber = 0;

                    foreach (BuildType buildType in teamProject.BuildTypes)
                    {
                        //if (columnNumber >= LayoutRoot.ColumnDefinitions.Count())
                        //    columnNumber = 0;

                        //if (columnNumber == 0)
                        //{
                        //    LayoutRoot.RowDefinitions.Add(new RowDefinition());
                        //}

                        BuildStatusControl control = new BuildStatusControl();

                        //control.SetValue(Grid.ColumnProperty, columnNumber);
                        //control.SetValue(Grid.RowProperty, LayoutRoot.RowDefinitions.Count() - 1);

                        control.TeamProjectName.Text = teamProject.Name;

                        control.BuildStatus.Text = buildType.Status;
                        control.BuildType.Text = buildType.Name;

                        String buildPostFix = "th";
                        if (buildType.NumberOfConsecutiveBuilds == 1)
                            buildPostFix = "st";
                        if (buildType.NumberOfConsecutiveBuilds == 2)
                            buildPostFix = "nd";

                        String statusText = "successful";

                        control.StatusImageRed.Visibility = Visibility.Collapsed;
                        control.StatusImageGreen.Visibility = Visibility.Collapsed;
                        control.StatusImageYellow.Visibility = Visibility.Collapsed;

                        if (buildType.Status == "Successfully Completed")
                        {
                            control.StatusImageGreen.Visibility = Visibility.Visible;
                        }
                        else if (buildType.Status == "Failed")
                        {
                            control.StatusImageRed.Visibility = Visibility.Visible;
                            statusText = "broken";
                        }
                        else
                        {
                            control.StatusImageYellow.Visibility = Visibility.Visible;
                        }

                        if (buildType.NumberOfConsecutiveBuilds > 0)
                        {
                            control.BuildTime.Text = String.Format("{0}{1} consecutive {2} build",
                                buildType.NumberOfConsecutiveBuilds,
                                buildPostFix, statusText);
                        }
                        else
                        {
                            control.BuildTime.Text = String.Format("Last updated on {0:dd/MM/yyyy HH:mm:ss}",
                                buildType.LastBuild);
                        }

                        LayoutRoot.Children.Add(control);

                        columnNumber++;
                    }
                }
            }
        }


        void client_GetBuildStatusCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            try
            {
                TeamProject[] teamProjects = ((GetBuildStatusCompletedEventArgs)(e)).Result.ToArray<TeamProject>();

                VerticalLayout(teamProjects);

                fader.Begin();
            }
            catch (Exception ex)
            {
            }
        }

        public List<IComponentParameter> ComponentParameters { get; set; }


    }
}
